home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / render2pixmap / fromxwd_1.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  12KB  |  441 lines

  1. /*
  2.  *    fromxwd -
  3.  *        Convert an xwd file to IRIS image file format.
  4.  *
  5.  * Copyright 1989 Massachusetts Institute of Technology
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and its
  8.  * documentation for any purpose is hereby granted without fee, provided that
  9.  * the above copyright notice appear in all copies and that both that
  10.  * copyright notice and this permission notice appear in supporting
  11.  * documentation, and that the name of M.I.T. not be used in advertising or
  12.  * publicity pertaining to distribution of the software without specific,
  13.  * written prior permission.  M.I.T. makes no representations about the
  14.  * suitability of this software for any purpose.  It is provided "as is"
  15.  * without express or implied warranty.
  16.  *
  17.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  18.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  19.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  20.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  21.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  22.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  23.  *
  24.  *                Paul Haeberli - 1990
  25.  */
  26. /*
  27.  * 
  28.  *   Modified by Ann LaGrone - 1994
  29.  *
  30.  *   this modified version works with XImage files, not xwd files.  i
  31.  *   Used with the offscreen_render.c program in this example
  32.  *   to convert an XImage to an sgi image format file.
  33.  *
  34.  */
  35.  
  36. #include <stdio.h>
  37. #include <X11/Xlib.h> 
  38. #include <X11/Xutil.h>
  39. #include <X11/XWDFile.h>
  40. #include <gl/image.h>
  41.  
  42. unsigned long MyXGetPixel();
  43. extern char *malloc();
  44. unsigned Image_Size();
  45.  
  46. writeimage(ximage, name )
  47. char *name;
  48. XImage *ximage;
  49. {
  50.     IMAGE *image;
  51.     int y, x, index;
  52.     int xsize, ysize;
  53.     int rshift = 0, gshift = 0, bshift = 0;
  54.     unsigned long rmask, gmask, bmask;
  55.     short *rbuf, *gbuf, *bbuf;
  56.  
  57.     xsize = ximage->width;
  58.     ysize = ximage->height;
  59.     rbuf = (short *)malloc(xsize*sizeof(short));
  60.     gbuf = (short *)malloc(xsize*sizeof(short));
  61.     bbuf = (short *)malloc(xsize*sizeof(short));
  62.     image = iopen(name,"w",RLE(1),3,xsize,ysize,3);
  63.     
  64.     if (rmask = ximage->red_mask){
  65.     while (!(rmask & 1)) {
  66.         rmask >>= 1;
  67.         rshift++;
  68.     }
  69.     }
  70.  
  71.     if (gmask = ximage->green_mask){
  72.     while (!(gmask & 1)) {
  73.         gmask >>= 1;
  74.         gshift++;
  75.     }
  76.     }
  77.  
  78.     if (bmask = ximage->blue_mask){
  79.     while (!(bmask & 1)) {
  80.         bmask >>= 1;
  81.         bshift++;
  82.     }
  83.     }
  84.  
  85.     for(y=0; y<ysize; y++) {
  86.     for(x=0; x<xsize; x++) {
  87.         index = MyXGetPixel(ximage,x,y);
  88.         rbuf[x] = (index>>rshift)&rmask;
  89.         gbuf[x] = (index>>gshift)&gmask;
  90.         bbuf[x] = (index>>bshift)&bmask;
  91.     }
  92.     putrow(image,rbuf,ysize-1-y,0);
  93.     putrow(image,gbuf,ysize-1-y,1);
  94.     putrow(image,bbuf,ysize-1-y,2);
  95.     }
  96.     iclose(image);
  97. }
  98.  
  99. unsigned Image_Size(xi)
  100. XWDFileHeader *xi;
  101. {
  102.     if (xi->pixmap_format == ZPixmap)
  103.     return ((unsigned)xi->bytes_per_line * xi->pixmap_height);
  104.     else
  105.           return (xi->bytes_per_line * xi->pixmap_depth * xi->pixmap_height);
  106. }
  107.  
  108. Error(string)
  109. char *string;
  110. {
  111.     fprintf(stderr, "xwud: Error => %s\n", string);
  112.     exit(1);
  113. }
  114.  
  115. _swapshort (bp, n)
  116. char *bp;
  117. unsigned n;
  118. {
  119.     char c;
  120.     char *ep = bp + n;
  121.  
  122.     while (bp < ep) {
  123.     c = *bp;
  124.     *bp = *(bp + 1);
  125.     bp++;
  126.     *bp++ = c;
  127.     }
  128. }
  129.  
  130. _swaplong (bp, n)
  131. char *bp;
  132. unsigned n;
  133. {
  134.     char c;
  135.     char *ep = bp + n;
  136.     char *sp;
  137.  
  138.     while (bp < ep) {
  139.     sp = bp + 3;
  140.     c = *sp;
  141.     *sp = *bp;
  142.     *bp++ = c;
  143.     sp = bp + 1;
  144.     c = *sp;
  145.     *sp = *bp;
  146.     *bp++ = c;
  147.     bp += 2;
  148.     }
  149. }
  150.  
  151. /*
  152.  *    XGetPixel follows
  153.  *
  154.  */
  155.  
  156. static unsigned char const _reverse_byte[0x100] = {
  157.     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
  158.     0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  159.     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
  160.     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  161.     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
  162.     0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
  163.     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
  164.     0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
  165.     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
  166.     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
  167.     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
  168.     0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
  169.     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
  170.     0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
  171.     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
  172.     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
  173.     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
  174.     0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
  175.     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
  176.     0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
  177.     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
  178.     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
  179.     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
  180.     0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  181.     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
  182.     0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  183.     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
  184.     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
  185.     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
  186.     0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
  187.     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
  188.     0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
  189. };
  190.  
  191. _Reverse_Bytes (bpt, nb)
  192.     unsigned char *bpt;
  193.     int nb;
  194. {
  195.     do {
  196.     *bpt = _reverse_byte[*bpt];
  197.     bpt++;
  198.     } while (--nb > 0);
  199.     return;
  200. }
  201.  
  202. static _normalizeimagebits (bpt, nb, byteorder, unitsize, bitorder)
  203.     unsigned char *bpt;    /* beginning pointer to image bits */
  204.     int nb;        /* number of bytes to normalize */
  205.     int byteorder;    /* swap bytes if byteorder == MSBFirst */
  206.     int unitsize;    /* size of the bitmap_unit or Zpixel */
  207.     int bitorder;    /* swap bits if bitorder == MSBFirst */
  208. {
  209.     if ((byteorder==MSBFirst) && (byteorder!=bitorder)) {
  210.         char c;
  211.         unsigned char *bp = bpt;
  212.         unsigned char *ep = bpt + nb;
  213.         unsigned char *sp;
  214.         switch (unitsize) {
  215.  
  216.         case 4:
  217.             do {            /* swap nibble */
  218.             *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
  219.             bp++;
  220.             }
  221.             while (bp < ep);
  222.             break;
  223.  
  224.         case 16:
  225.             do {            /* swap short */
  226.             c = *bp;
  227.             *bp = *(bp + 1);
  228.             bp++;
  229.             *bp = c;
  230.             bp++;
  231.             }
  232.             while (bp < ep);
  233.             break;
  234.  
  235.         case 24:
  236.             do {            /* swap three */
  237.             c = *(bp + 2);
  238.             *(bp + 2) = *bp;
  239.             *bp = c;
  240.             bp += 3;        
  241.             }
  242.             while (bp < ep);
  243.             break;
  244.  
  245.         case 32:
  246.             do {            /* swap long */
  247.             sp = bp + 3;
  248.             c = *sp;
  249.             *sp = *bp;
  250.             *bp++ = c;
  251.             sp = bp + 1;
  252.             c = *sp;
  253.             *sp = *bp;
  254.             *bp++ = c;
  255.             bp += 2;
  256.             }
  257.             while (bp < ep);
  258.             break;
  259.         }
  260.     }
  261.     if (bitorder == MSBFirst) {
  262.         _Reverse_Bytes (bpt, nb);
  263.     }
  264. }
  265.  
  266. /*
  267.  * Macros
  268.  * 
  269.  * The ROUNDUP macro rounds up a quantity to the specified boundary.
  270.  *
  271.  * The XYNORMALIZE macro determines whether XY format data requires 
  272.  * normalization and calls a routine to do so if needed. The logic in
  273.  * this module is designed for LSBFirst byte and bit order, so 
  274.  * normalization is done as required to present the data in this order.
  275.  *
  276.  * The ZNORMALIZE macro performs byte and nibble order normalization if 
  277.  * required for Z format data.
  278.  *
  279.  * The XYINDEX macro computes the index to the starting byte (char) boundary
  280.  * for a bitmap_unit containing a pixel with coordinates x and y for image
  281.  * data in XY format.
  282.  * 
  283.  * The ZINDEX macro computes the index to the starting byte (char) boundary 
  284.  * for a pixel with coordinates x and y for image data in ZPixmap format.
  285.  * 
  286.  */
  287.  
  288. #define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad) - 1)) / (pad)) * (pad))
  289.  
  290. #define XYNORMALIZE(bp, nbytes, img) \
  291.     if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \
  292.     _normalizeimagebits((unsigned char *)(bp), (nbytes), img->byte_order, img->bitmap_unit, \
  293.         img->bitmap_bit_order)
  294.  
  295. #define ZNORMALIZE(bp, nbytes, img) \
  296.     if (img->byte_order == MSBFirst) \
  297.     _normalizeimagebits((unsigned char *)(bp), (nbytes), MSBFirst, img->bits_per_pixel, \
  298.     LSBFirst)
  299.  
  300. #define XYINDEX(x, y, img) \
  301.     ((y) * img->bytes_per_line) + \
  302.     (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3)
  303.  
  304. #define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \
  305.     (((x) * img->bits_per_pixel) >> 3)
  306.  
  307. /*
  308.  * GetPixel
  309.  * 
  310.  * Returns the specified pixel.  The X and Y coordinates are relative to 
  311.  * the origin (upper left [0,0]) of the image.  The pixel value is returned
  312.  * in normalized format, i.e. the LSB of the long is the LSB of the pixel.
  313.  * The algorithm used is:
  314.  *
  315.  *    copy the source bitmap_unit or Zpixel into temp
  316.  *    normalize temp if needed
  317.  *    extract the pixel bits into return value
  318.  *
  319.  */
  320.  
  321. static unsigned long const low_bits_table[] = {
  322.     0x00000000, 0x00000001, 0x00000003, 0x00000007,
  323.     0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
  324.     0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
  325.     0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
  326.     0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
  327.     0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
  328.     0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
  329.     0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
  330.     0xffffffff
  331. };
  332.  
  333. static unsigned long _XGetPixel (ximage, x, y)
  334. XImage *ximage;
  335. int x;
  336. int y;
  337. {
  338.     unsigned long pixel, px;
  339.     char *src;
  340.     char *dst;
  341.     int i, j;
  342.     int bits, nbytes;
  343.     long plane;
  344.      
  345.     if (ximage->depth == 1) {
  346.         src = &ximage->data[XYINDEX(x, y, ximage)];
  347.         dst = (char *)&pixel;
  348.         pixel = 0;
  349.         nbytes = ximage->bitmap_unit >> 3;
  350.         for (i=0; i < nbytes; i++) *dst++ = *src++;
  351.         XYNORMALIZE(&pixel, nbytes, ximage);
  352.               bits = (x + ximage->xoffset) % ximage->bitmap_unit;
  353.         pixel = ((((char *)&pixel)[bits>>3])>>(bits&7)) & 1;
  354.     } else if (ximage->format == XYPixmap) {
  355.         pixel = 0;
  356.         plane = 0;
  357.         nbytes = ximage->bitmap_unit >> 3;
  358.         for (i=0; i < ximage->depth; i++) {
  359.             src = &ximage->data[XYINDEX(x, y, ximage)+ plane];
  360.             dst = (char *)&px;
  361.             px = 0;
  362.             for (j=0; j < nbytes; j++) *dst++ = *src++;
  363.             XYNORMALIZE(&px, nbytes, ximage);
  364.             bits = (x + ximage->xoffset) % ximage->bitmap_unit;
  365.             pixel = (pixel << 1) |
  366.                 (((((char *)&px)[bits>>3])>>(bits&7)) & 1);
  367.             plane = plane + (ximage->bytes_per_line * ximage->height);
  368.         }
  369.     } else if (ximage->format == ZPixmap) {
  370.         src = &ximage->data[ZINDEX(x, y, ximage)];
  371.         dst = (char *)&px;
  372.         px = 0;
  373.         nbytes = ROUNDUP(ximage->bits_per_pixel, 8) >> 3;
  374.         for (i=0; i < nbytes; i++) *dst++ = *src++;        
  375.         ZNORMALIZE(&px, nbytes, ximage);
  376.         pixel = 0;
  377.         for (i=sizeof(unsigned long); --i >= 0; )
  378.             pixel = (pixel << 8) | ((unsigned char *)&px)[i];
  379.         if (ximage->bits_per_pixel == 4) {
  380.             if (x & 1)
  381.             pixel >>= 4;
  382.             else
  383.             pixel &= 0xf;
  384.         }
  385.     } else {
  386.         fprintf(stderr, "XGetPixel: bad image!!\n");
  387.         exit(1);
  388.     }
  389.     if (ximage->bits_per_pixel == ximage->depth)
  390.       return pixel;
  391.     else
  392.       return (pixel & low_bits_table[ximage->depth]);
  393. }
  394.  
  395. static unsigned long _XGetPixel8 (ximage, x, y)
  396. XImage *ximage;
  397. int x;
  398. int y;
  399. {
  400.     unsigned char pixel;
  401.  
  402.     pixel = ((unsigned char *)ximage->data)
  403.             [y * ximage->bytes_per_line + x];
  404.     if (ximage->depth != 8)
  405.         pixel &= low_bits_table[ximage->depth];
  406.     return pixel;
  407. }
  408.  
  409. static unsigned long _XGetPixel1 (ximage, x, y)
  410. XImage *ximage;
  411. int x;
  412. int y;
  413. {
  414.     unsigned char bit;
  415.     int xoff, yoff;
  416.  
  417.     xoff = x + ximage->xoffset;
  418.     yoff = y * ximage->bytes_per_line + (xoff >> 3);
  419.     xoff &= 7;
  420.     if (ximage->bitmap_bit_order == MSBFirst)
  421.         bit = 0x80 >> xoff;
  422.     else
  423.         bit = 1 << xoff;
  424.     return (ximage->data[yoff] & bit) ? 1 : 0;
  425. }
  426.     
  427. unsigned long MyXGetPixel (image, x, y)
  428. XImage *image;
  429. int x;
  430. int y;
  431. {
  432.     if ((image->format == ZPixmap) && (image->bits_per_pixel == 8)) {
  433.         return _XGetPixel8(image,x,y);
  434.     } else if ((image->depth == 1) &&
  435.            (image->byte_order == image->bitmap_bit_order)) {
  436.         return _XGetPixel1(image,x,y);
  437.     } else {
  438.         return _XGetPixel(image,x,y);
  439.     }
  440. }
  441.